package at.jku.ssw.fortress.ui;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.osgi.framework.Bundle;


public class Macros {

	public static class Macro implements Comparable<Macro> {
		public String name;
		public char ch;
		public String ascii;

		public Macro(String name, char ch) {
			super();
			this.name = name;
			this.ch = ch;
		}
		
		public Macro(String name, char ch, String ascii) {
			super();
			this.name = name;
			this.ch = ch;
			this.ascii = ascii;
		}

		@Override
		public boolean equals(Object obj) {
			if (!(obj instanceof Macro)) {
				return false;
			}
			Macro o = (Macro) obj;
			return name.equals(o.name);
		}

		public int compareTo(Macro o) {
			return name.compareTo(o.name);
		}
	}

	private Macro[] characters;
	private boolean sorted;

	public Macros(String file, boolean sort) {
		ArrayList<Macro> list = new ArrayList<Macro>();
		try {
			Bundle plugin = Platform.getBundle(FortressPlugin.PLUGIN_ID);
			URL url = FileLocator.find(plugin, Path.fromOSString(file), null);
			BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream()));
			String line;
			while ((line = r.readLine()) != null) {
				if(line.replace(" ", "").length() == 0 || line.charAt(0) == '#') continue;
				
				String[] parts = line.split(";");
				String code = parts[0];
				String name = parts[1];
				String ascii = "";
				if(parts.length > 2) {
					ascii = parts[2];
				}
				char c = (char) Integer.parseInt(code, 16);
				name = name.replace(" ", "_");
				
				if(!name.startsWith("<")) {
					list.add(new Macro(name, c, ascii));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		characters = list.toArray(new Macro[list.size()]);
		if(sort) {
			Arrays.sort(characters);
		}
		sorted = sort;
	}

	public Macro[] search(String name) {
		return sorted ? searchSorted(name) : searchUnsorted(name);
	}

	private Macro[] searchSorted(String name) {
		name = name.toLowerCase();
		int pos = Arrays.binarySearch(characters, new Macro(name,'0'));
		if(pos < 0) pos = -pos - 1;
		ArrayList<Macro> list = new ArrayList<Macro>();
		while (pos < characters.length && characters[pos].name.startsWith(name)) {
			list.add(characters[pos]);
			pos++;
		}
		return list.toArray(new Macro[list.size()]);
	}
	
	public Macro[] getMacros() {
		return characters;
	}
	
	private Macro[] searchUnsorted(String name) {
		name = name.toLowerCase();
		ArrayList<Macro> list = new ArrayList<Macro>();
		for(Macro c : characters) {
			if(c.name.startsWith(name)) {
				list.add(c);
			}
		}
		return list.toArray(new Macro[list.size()]);
	}

}